home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ada
/
gwuada_9.zip
/
PREDEF2.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-27
|
15KB
|
463 lines
/*
* Copyright (C) 1985-1992 New York University
*
* This file is part of the Ada/Ed-C system. See the Ada/Ed README file for
* warranty (none) and distribution info and also the GNU General Public
* License for more details.
*/
/* +---------------------------------------------------+
| |
| I N T E R P P R E D E F S |
| Part 2: CALENDAR Procedure |
| (C Version) |
| |
| Adapted From Low Level SETL version written by |
| |
| Monte Zweben |
| Philippe Kruchten |
| Jean-Pierre Rosen |
| |
| Original High Level SETL version written by |
| |
| Clint Goss |
| Tracey M. Siesser |
| Bernard D. Banner |
| Stephen C. Bryant |
| Gerry Fisher |
| |
| C version written by |
| |
| Robert B. K. Dewar |
| |
+---------------------------------------------------+
*/
/* This module contains the implementation of the CALENDAR package */
#include "ipredef.h"
#include "time.h"
#include "intbp.h"
#include "intcp.h"
#include "predefp.h"
#include <conio.h>
/* Structure corresponding to Ada record TIME */
struct time_record {
int year_val;
int month_val;
int day_val;
long secs_val;
};
static long days_in(int, int, int);
static void ymd_of(long days, int *, int *, int *);
static void get_time(struct time_record *);
/* Macros for treating pointer as pointer to time_record, and length in
* words of time record(used when creating an object of this type.
*/
#define TIME_RECORD(ptr) ((struct time_record *)(ptr))
#define WORDS_TIME_RECORD (sizeof(struct time_record) / sizeof (int))
/* Constants for CALENDAR */
#define ONE_DAY 86400000L /* 24 * 60 * 60 * 1000 (milliseconds) */
static int days_before_month[] = {
0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
};
static int days_in_month[] = {
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
/* CALENDAR */
/* Control passes to the CALENDAR procedure from PREDEF when it encounters an
* operation code value corresponding to a predefined calendar operation.
*/
void calendar() /*;calendar*/
{
switch(operation) {
/* function CLOCK return TIME; */
case P_CLOCK:
{
int bse, off;
int *ptr;
create(WORDS_TIME_RECORD, &bse, &off, &ptr);
get_time((struct time_record *) ptr);
TOSM(1) = bse;
TOS = off;
break;
}
/* function YEAR(DATE : in TIME) return YEAR_NUMBER; */
case P_YEAR:
TOSM(2) = TIME_RECORD(get_argument_ptr(0)) -> year_val;
break;
/* function MONTH(DATE : in TIME) return MONTH_NUMBER; */
case P_MONTH:
TOSM(2) = TIME_RECORD(get_argument_ptr(0)) -> month_val;
break;
/* function DAY(DATE : in TIME) return DAY_NUMBER; */
case P_DAY:
TOSM(2) = TIME_RECORD(get_argument_ptr(0)) -> day_val;
break;
/* function SECONDS(DATE : in TIME) return DURATION; */
case P_SECONDS:
{
int bse,off;
long secs,tmp;
/*TOSM(2) = TIME_RECORD(get_argument_ptr(0)) -> secs_val;*/
/* direct code needed since TOSML macro wrong */
/* pop arguments, store long and restore args */
secs = TIME_RECORD(get_argument_ptr(0)) -> secs_val;
/*WAS AVL secs = TIME_RECORD(get_argument_ptr(0)) -> secs_val;
*/
POP_ADDR(bse,off);
POPL(tmp); /* pop current value */
PUSHL(secs); /* push correct value */
PUSH_ADDR(bse,off); /* restore arg on stack */
}
break;
/* procedure SPLIT(DATE : in TIME; */
/* YEAR : out YEAR_NUMBER; */
/* MONTH : out MONTH_NUMBER; */
/* DAY : out DAY_NUMBER; */
/* SECONDS : out DURATION); */
case P_SPLIT:
{
struct time_record *time_ptr;
long *p;
time_ptr = TIME_RECORD(get_argument_ptr(0));
*get_argument_ptr(2) = time_ptr -> year_val;
*get_argument_ptr(6) = time_ptr -> month_val;
*get_argument_ptr(10) = time_ptr -> day_val;
p = (long *) get_argument_ptr(14) ;
*p = time_ptr -> secs_val;
break;
}
/* function TIME_OF(YEAR : YEAR_NUMBER; */
/* MONTH : MONTH_NUMBER; */
/* DAY : DAY_NUMBER; */
/* SECONDS : DURATION := 0.0) return TIME; */
case P_TIME_OF:
{
int year, month, day;
long secs;
long days;
int bse, off;
struct time_record *time_ptr;
year = get_argument_value(0);
month = get_argument_value(2);
day = get_argument_value(4);
secs = get_long_argument_value(6);
if ((year % 4) == 0 && month == 2) {
if (day > 29) { /* check leap year */
raise(TIME_ERROR, "Day too large");
return;
}
}
else if (day > days_in_month[month]) {
raise(TIME_ERROR, "Day too large");
return;
}
if (secs >= ONE_DAY) {
secs -= ONE_DAY;
days = days_in(year, month, day + 1);
ymd_of(days, &year, &month, &day);
if (year < 1901 || year > 2099) {
raise(TIME_ERROR, "Year out of range");
return;
}
}
create(WORDS_TIME_RECORD, &bse, &off,(int **)(&time_ptr));
time_ptr -> year_val = year;
time_ptr -> month_val = month;
time_ptr -> day_val = day;
time_ptr -> secs_val = secs;
TOSM(9) = bse;
TOSM(8) = off;
break;
}
/* function "+"(LEFT : TIME; RIGHT : DURATION) return TIME; */
/* function "+"(LEFT : DURATION; RIGHT : TIME) return TIME; */
/* function "-"(LEFT : TIME; RIGHT : DURATION) return TIME; */
case P_ADD_TIME_DUR:
case P_ADD_DUR_TIME:
case P_SUB_TIME_DUR:
{
struct time_record *time_ptr;
long dur;
int year, month, day;
long secs,days;
int add_day;
int bse, off;
if (operation == P_ADD_TIME_DUR) {
time_ptr = TIME_RECORD(get_argument_ptr(0));
dur = get_long_argument_value(2);
}
else if (operation == P_ADD_DUR_TIME) {
dur = get_long_argument_value(0);
time_ptr = TIME_RECORD(get_argument_ptr(2));
}
else { /* operation == P_SUB_TIME_DUR */
time_ptr = TIME_RECORD(get_argument_p